package com.xyd.wechat.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xyd.wechat.common.ApplicationConfig;
import com.xyd.wechat.common.MsgTypeEnum;
import com.xyd.wechat.service.AccessTokenService;
import com.xyd.wechat.service.MaterialService;
import com.xyd.wechat.vo.ContentNewsVo;
import com.xyd.wechat.vo.ItemNewsVo;
import com.xyd.wechat.vo.ItemVo;
import com.xyd.wechat.vo.MaterialVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class MaterialServiceImpl implements MaterialService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private AccessTokenService accessTokenService;

    @Autowired
    private ApplicationConfig applicationConfig;

    @Autowired
    private RestTemplate restTemplate;

    private Map<String, List<MaterialVo>> materialVoMap = new HashMap<String, List<MaterialVo>>();

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 返回素材的数量，取值在1到20之间
     */
    private final Integer count = 20;
    /**
     * 该类型的素材的总数
     */
    private Integer totalMaterial = 0;
    /**
     * 已获取总数
     */
    private Integer currentMaterial = 0;

    public void initMaterial() throws Exception {
        Integer offset = 0;
        // 获取图片素材
        while ((totalMaterial != currentMaterial) || (totalMaterial == 0 && currentMaterial == 0)) {
            getMaterial(offset, MsgTypeEnum.IMAGE.getType());
            offset += count;
        }
        // 获取图文素材
        offset = 0;
        totalMaterial = 0;
        currentMaterial = 0;
        while ((totalMaterial != currentMaterial) || (totalMaterial == 0 && currentMaterial == 0)) {
            getMaterial(offset, MsgTypeEnum.NEWS.getType());
            offset += count;
        }
    }

    public void getMaterial(Integer offset, String type) throws Exception {
        String url = String.format(applicationConfig.getWechatBatchgetMaterialUrl(), accessTokenService.getAccessToken());
        ObjectNode node = objectMapper.createObjectNode();
        node.put("type", type);
        node.put("offset", String.valueOf(offset));
        node.put("count", count.toString());
        ResponseEntity<String> entity = restTemplate.postForEntity(url, node.toString(), String.class);
        String body = entity.getBody();
        logger.info("获取素材[{}]返回结果：{}", type, body);
        MaterialVo materialVo = objectMapper.readValue(body, MaterialVo.class);
        if (materialVo.getItem_count() == 0) {
            currentMaterial = totalMaterial;
        } else {
            totalMaterial = materialVo.getTotal_count();
            currentMaterial += materialVo.getItem_count();
            List<MaterialVo> materialVoList = materialVoMap.get(type);
            if (materialVoList == null) {
                materialVoList = new ArrayList<MaterialVo>();
            }
            materialVoList.add(materialVo);
            materialVoMap.put(type, materialVoList);
        }
    }

    /**
     * 根据类型，关键字获取素材mediaID
     *
     * @param type
     * @param keyword
     * @return 素材mediaID
     */
    @Override
    public String getMediaId(String type, String keyword) {
        try {
            List<MaterialVo> materialVoList = materialVoMap.get(type);
            if (materialVoList == null) {
                initMaterial();
            }
            materialVoList = materialVoMap.get(type);
            if (materialVoList != null) {
                for (MaterialVo materialVo : materialVoList) {
                    List<ItemVo> itemVoList = materialVo.getItem();
                    for (int i = 0; i < itemVoList.size(); i++) {
                        ItemVo itemVo = itemVoList.get(i);
                        if (type.equals(MsgTypeEnum.NEWS.getType())) { // 获取图文消息 media id
                            ContentNewsVo content = itemVo.getContent();
                            List<ItemNewsVo> itemNewsVoList = content.getNews_item();
                            for (ItemNewsVo itemNewsVo : itemNewsVoList) {
                                if (keyword.equals(itemNewsVo.getTitle())) {
                                    return itemVo.getMedia_id();
                                }
                            }
                        } else { // 获取 图片、语音、视频 media id
                            if (keyword.equals(itemVo.getName())) {
                                return itemVo.getMedia_id();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("根据类型，关键字获取素材mediaID,发生异常。", e);
        }
        return null;
    }
}
